package com.hdax.dm.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

@Component
public class AuthFilter extends ZuulFilter {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override       //前置过滤器
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override       //过滤器是否生效
    public boolean shouldFilter() {
        boolean requieAuth = false;
        //从requestContext获取应用上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        //从应用上下文获取HttpServletRequest
        HttpServletRequest request = ctx.getRequest();
        //从request获取请求路径
        String uri = request.getRequestURI();
        if (uri.contains("/p/") || uri.contains("/order/")) {
            requieAuth = true;
        }
        return requieAuth;
    }

    @Override       //鉴权
    public Object run() throws ZuulException {
        //获取用户请求时携带的token信息
        //从requestContext获取应用上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        //从应用上下文获取request对象
        HttpServletRequest request = ctx.getRequest();
        String userToken = request.getHeader("token");
        //判断token是否存在
        String userInfoStr = redisTemplate.opsForValue().get("token:"+userToken);
         if (userInfoStr == null){
            //对该请求禁止路由,也就是禁止访问下游服务
            ctx.setSendZuulResponse(false);
            //设定responseBody供PostFilter使用
            ctx.setResponseBody("{\"errorCode\":\"403\",\"msg\":\"登陆超时，请重新登录\"}");
            return ctx;
        }
        //判断是否需要对redis中的token续期
        long genTime = Long.parseLong(userToken.split("-")[2]);
        long currTime = System.currentTimeMillis();     //当前时间
        if (currTime - genTime <= 5 * 60 * 1000) {
            //重置过期时间
            redisTemplate.expire(userToken,2L, TimeUnit.HOURS);
        }
        ctx.addZuulRequestHeader("token",userToken);
        return ctx;
    }
}
